/* 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Generated By:JavaCC: Do not edit this line. QueryParser.java */

using System;

using Analyzer = Lucene.Net.Analysis.Analyzer;
using CachingTokenFilter = Lucene.Net.Analysis.CachingTokenFilter;
using TokenStream = Lucene.Net.Analysis.TokenStream;
using PositionIncrementAttribute = Lucene.Net.Analysis.Tokenattributes.PositionIncrementAttribute;
using TermAttribute = Lucene.Net.Analysis.Tokenattributes.TermAttribute;
using DateField = Lucene.Net.Documents.DateField;
using DateTools = Lucene.Net.Documents.DateTools;
using Term = Lucene.Net.Index.Term;
using Parameter = Lucene.Net.Util.Parameter;
using BooleanClause = Lucene.Net.Search.BooleanClause;
using BooleanQuery = Lucene.Net.Search.BooleanQuery;
using FuzzyQuery = Lucene.Net.Search.FuzzyQuery;
using MatchAllDocsQuery = Lucene.Net.Search.MatchAllDocsQuery;
using MultiPhraseQuery = Lucene.Net.Search.MultiPhraseQuery;
using MultiTermQuery = Lucene.Net.Search.MultiTermQuery;
using PhraseQuery = Lucene.Net.Search.PhraseQuery;
using PrefixQuery = Lucene.Net.Search.PrefixQuery;
using Query = Lucene.Net.Search.Query;
using TermQuery = Lucene.Net.Search.TermQuery;
using TermRangeQuery = Lucene.Net.Search.TermRangeQuery;
using WildcardQuery = Lucene.Net.Search.WildcardQuery;
using Version = Lucene.Net.Util.Version;

namespace Lucene.Net.QueryParsers
{
	
	/// <summary> This class is generated by JavaCC.  The most important method is
	/// {@link #Parse(String)}.
	/// 
	/// The syntax for query strings is as follows:
	/// A Query is a series of clauses.
	/// A clause may be prefixed by:
	/// <ul>
	/// <li> a plus (<code>+</code>) or a minus (<code>-</code>) sign, indicating
	/// that the clause is required or prohibited respectively; or</li>
	/// <li> a term followed by a colon, indicating the field to be searched.
	/// This enables one to construct queries which search multiple fields.</li>
	/// </ul>
	/// 
	/// A clause may be either:
	/// <ul>
	/// <li> a term, indicating all the documents that contain this term; or</li>
	/// <li> a nested query, enclosed in parentheses.  Note that this may be used
	/// with a <code>+</code>/<code>-</code> prefix to require any of a set of
	/// terms.</li>
	/// </ul>
	/// 
	/// Thus, in BNF, the query grammar is:
	/// <pre>
	/// Query  ::= ( Clause )*
	/// Clause ::= ["+", "-"] [&lt;TERM&gt; ":"] ( &lt;TERM&gt; | "(" Query ")" )
	/// </pre>
	/// 
	/// <p/>
	/// Examples of appropriately formatted queries can be found in the <a
	/// href="../../../../../../queryparsersyntax.html">query syntax
	/// documentation</a>.
	/// <p/>
	/// 
	/// <p/>
	/// In {@link TermRangeQuery}s, QueryParser tries to detect date values, e.g.
	/// <tt>date:[6/1/2005 TO 6/4/2005]</tt> produces a range query that searches
	/// for "date" fields between 2005-06-01 and 2005-06-04. Note that the format
	/// of the accepted input depends on {@link #SetLocale(Locale) the locale}.
	/// By default a date is converted into a search term using the deprecated
	/// {@link DateField} for compatibility reasons.
	/// To use the new {@link DateTools} to convert dates, a
	/// {@link Lucene.Net.Documents.DateTools.Resolution} has to be set.
	/// <p/>
	/// <p/>
	/// The date resolution that shall be used for RangeQueries can be set
	/// using {@link #SetDateResolution(DateTools.Resolution)}
	/// or {@link #SetDateResolution(String, DateTools.Resolution)}. The former
	/// sets the default date resolution for all fields, whereas the latter can
	/// be used to set field specific date resolutions. Field specific date
	/// resolutions take, if set, precedence over the default date resolution.
	/// <p/>
	/// <p/>
	/// If you use neither {@link DateField} nor {@link DateTools} in your
	/// index, you can create your own
	/// query parser that inherits QueryParser and overwrites
	/// {@link #GetRangeQuery(String, String, String, boolean)} to
	/// use a different method for date conversion.
	/// <p/>
	/// 
	/// <p/>Note that QueryParser is <em>not</em> thread-safe.<p/> 
	/// 
	/// <p/><b>NOTE</b>: there is a new QueryParser in contrib, which matches
	/// the same syntax as this class, but is more modular,
	/// enabling substantial customization to how a query is created.
	/// 
	/// <p/><b>NOTE</b>: there is a new QueryParser in contrib, which matches
	/// the same syntax as this class, but is more modular,
	/// enabling substantial customization to how a query is created.
	/// <b>NOTE</b>: You must specify the required {@link Version} compatibility when
	/// creating QueryParser:
	/// <ul>
	/// <li>As of 2.9, {@link #SetEnablePositionIncrements} is true by default.</li>
	/// </ul>
	/// </summary>
	public class QueryParser : QueryParserConstants
	{
		private void  InitBlock()
		{
			multiTermRewriteMethod = MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
			fuzzyMinSim = FuzzyQuery.defaultMinSimilarity;
			fuzzyPrefixLength = FuzzyQuery.defaultPrefixLength;
			jj_2_rtns = new JJCalls[1];
			jj_ls = new LookaheadSuccess();
		}
		
		private const int CONJ_NONE = 0;
		private const int CONJ_AND = 1;
		private const int CONJ_OR = 2;
		
		private const int MOD_NONE = 0;
		private const int MOD_NOT = 10;
		private const int MOD_REQ = 11;
		
		// make it possible to call setDefaultOperator() without accessing 
		// the nested class:
		/// <summary>Alternative form of QueryParser.Operator.AND </summary>
		public static readonly Operator AND_OPERATOR = Operator.AND;
		/// <summary>Alternative form of QueryParser.Operator.OR </summary>
		public static readonly Operator OR_OPERATOR = Operator.OR;
		
		/// <summary>The actual operator that parser uses to combine query terms </summary>
		private Operator operator_Renamed = OR_OPERATOR;
		
		internal bool lowercaseExpandedTerms = true;
		internal MultiTermQuery.RewriteMethod multiTermRewriteMethod;
		internal bool allowLeadingWildcard = false;
		internal bool enablePositionIncrements = true;
		
		internal Analyzer analyzer;
		internal System.String field;
		internal int phraseSlop = 0;
		internal float fuzzyMinSim;
		internal int fuzzyPrefixLength;
		internal System.Globalization.CultureInfo locale = System.Threading.Thread.CurrentThread.CurrentCulture;
		
		// the default date resolution
		internal DateTools.Resolution dateResolution = null;
		// maps field names to date resolutions
		internal System.Collections.IDictionary fieldToDateResolution = null;
		
		// The collator to use when determining range inclusion,
		// for use when constructing RangeQuerys.
		internal System.Globalization.CompareInfo rangeCollator = null;
		
		/// <summary>The default operator for parsing queries. 
		/// Use {@link QueryParser#setDefaultOperator} to change it.
		/// </summary>
		[Serializable]
		public sealed class Operator:Parameter
		{
			internal Operator(System.String name):base(name)
			{
			}
			public static readonly Operator OR = new Operator("OR");
			public static readonly Operator AND = new Operator("AND");
		}
		
		
		/// <summary>Constructs a query parser.</summary>
		/// <param name="f"> the default field for query terms.
		/// </param>
		/// <param name="a">  used to find terms in the query text.
		/// </param>
		/// <deprecated> Use {@link #QueryParser(Version, String, Analyzer)} instead
		/// </deprecated>
        [Obsolete("Use QueryParser(Version, String, Analyzer) instead")]
		public QueryParser(System.String f, Analyzer a):this(Version.LUCENE_24, f, a)
		{
		}
		
		/// <summary> Constructs a query parser.
		/// 
		/// </summary>
		/// <param name="matchVersion">Lucene version to match. See <a href="#version">above</a>)
		/// </param>
		/// <param name="f">the default field for query terms.
		/// </param>
		/// <param name="a">used to find terms in the query text.
		/// </param>
		public QueryParser(Version matchVersion, System.String f, Analyzer a):this(new FastCharStream(new System.IO.StringReader("")))
		{
			analyzer = a;
			field = f;
			if (matchVersion.OnOrAfter(Version.LUCENE_29))
			{
				enablePositionIncrements = true;
			}
			else
			{
				enablePositionIncrements = false;
			}
		}
		
		/// <summary>Parses a query string, returning a {@link Lucene.Net.Search.Query}.</summary>
		/// <param name="query"> the query string to be parsed.
		/// </param>
		/// <throws>  ParseException if the parsing fails </throws>
		public virtual Query Parse(System.String query)
		{
			ReInit(new FastCharStream(new System.IO.StringReader(query)));
			try
			{
				// TopLevelQuery is a Query followed by the end-of-input (EOF)
				Query res = TopLevelQuery(field);
				return res != null?res:NewBooleanQuery(false);
			}
			catch (ParseException tme)
			{
				// rethrow to include the original query:
				ParseException e = new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
				throw e;
			}
			catch (TokenMgrError tme)
			{
				ParseException e = new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
				throw e;
			}
			catch (BooleanQuery.TooManyClauses tmc)
			{
				ParseException e = new ParseException("Cannot parse '" + query + "': too many boolean clauses", tmc);
				throw e;
			}
		}
		
		/// <returns> Returns the analyzer.
		/// </returns>
		public virtual Analyzer GetAnalyzer()
		{
			return analyzer;
		}
		
		/// <returns> Returns the field.
		/// </returns>
		public virtual System.String GetField()
		{
			return field;
		}
		
		/// <summary> Get the minimal similarity for fuzzy queries.</summary>
		public virtual float GetFuzzyMinSim()
		{
			return fuzzyMinSim;
		}
		
		/// <summary> Set the minimum similarity for fuzzy queries.
		/// Default is 0.5f.
		/// </summary>
		public virtual void  SetFuzzyMinSim(float fuzzyMinSim)
		{
			this.fuzzyMinSim = fuzzyMinSim;
		}
		
		/// <summary> Get the prefix length for fuzzy queries. </summary>
		/// <returns> Returns the fuzzyPrefixLength.
		/// </returns>
		public virtual int GetFuzzyPrefixLength()
		{
			return fuzzyPrefixLength;
		}
		
		/// <summary> Set the prefix length for fuzzy queries. Default is 0.</summary>
		/// <param name="fuzzyPrefixLength">The fuzzyPrefixLength to set.
		/// </param>
		public virtual void  SetFuzzyPrefixLength(int fuzzyPrefixLength)
		{
			this.fuzzyPrefixLength = fuzzyPrefixLength;
		}
		
		/// <summary> Sets the default slop for phrases.  If zero, then exact phrase matches
		/// are required.  Default value is zero.
		/// </summary>
		public virtual void  SetPhraseSlop(int phraseSlop)
		{
			this.phraseSlop = phraseSlop;
		}
		
		/// <summary> Gets the default slop for phrases.</summary>
		public virtual int GetPhraseSlop()
		{
			return phraseSlop;
		}
		
		
		/// <summary> Set to <code>true</code> to allow leading wildcard characters.
		/// <p/>
		/// When set, <code>*</code> or <code>?</code> are allowed as 
		/// the first character of a PrefixQuery and WildcardQuery.
		/// Note that this can produce very slow
		/// queries on big indexes. 
		/// <p/>
		/// Default: false.
		/// </summary>
		public virtual void  SetAllowLeadingWildcard(bool allowLeadingWildcard)
		{
			this.allowLeadingWildcard = allowLeadingWildcard;
		}
		
		/// <seealso cref="SetAllowLeadingWildcard(boolean)">
		/// </seealso>
		public virtual bool GetAllowLeadingWildcard()
		{
			return allowLeadingWildcard;
		}
		
		/// <summary> Set to <code>true</code> to enable position increments in result query.
		/// <p/>
		/// When set, result phrase and multi-phrase queries will
		/// be aware of position increments.
		/// Useful when e.g. a StopFilter increases the position increment of
		/// the token that follows an omitted token.
		/// <p/>
		/// Default: false.
		/// </summary>
		public virtual void  SetEnablePositionIncrements(bool enable)
		{
			this.enablePositionIncrements = enable;
		}
		
		/// <seealso cref="SetEnablePositionIncrements(boolean)">
		/// </seealso>
		public virtual bool GetEnablePositionIncrements()
		{
			return enablePositionIncrements;
		}
		
		/// <summary> Sets the boolean operator of the QueryParser.
		/// In default mode (<code>OR_OPERATOR</code>) terms without any modifiers
		/// are considered optional: for example <code>capital of Hungary</code> is equal to
		/// <code>capital OR of OR Hungary</code>.<br/>
		/// In <code>AND_OPERATOR</code> mode terms are considered to be in conjunction: the
		/// above mentioned query is parsed as <code>capital AND of AND Hungary</code>
		/// </summary>
		public virtual void  SetDefaultOperator(Operator op)
		{
			this.operator_Renamed = op;
		}
		
		
		/// <summary> Gets implicit operator setting, which will be either AND_OPERATOR
		/// or OR_OPERATOR.
		/// </summary>
		public virtual Operator GetDefaultOperator()
		{
			return operator_Renamed;
		}
		
		
		/// <summary> Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically
		/// lower-cased or not.  Default is <code>true</code>.
		/// </summary>
		public virtual void  SetLowercaseExpandedTerms(bool lowercaseExpandedTerms)
		{
			this.lowercaseExpandedTerms = lowercaseExpandedTerms;
		}
		
		
		/// <seealso cref="SetLowercaseExpandedTerms(boolean)">
		/// </seealso>
		public virtual bool GetLowercaseExpandedTerms()
		{
			return lowercaseExpandedTerms;
		}
		
		/// <deprecated> Please use {@link #setMultiTermRewriteMethod} instead.
		/// </deprecated>
        [Obsolete("Please use SetMultiTermRewriteMethod instead.")]
		public virtual void  SetUseOldRangeQuery(bool useOldRangeQuery)
		{
			if (useOldRangeQuery)
			{
				SetMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
			}
			else
			{
				SetMultiTermRewriteMethod(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT);
			}
		}
		
		
		/// <deprecated> Please use {@link #getMultiTermRewriteMethod} instead.
		/// </deprecated>
        [Obsolete("Please use GetMultiTermRewriteMethod} instead.")]
		public virtual bool GetUseOldRangeQuery()
		{
			if (GetMultiTermRewriteMethod() == MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		
		/// <summary> By default QueryParser uses {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT}
		/// when creating a PrefixQuery, WildcardQuery or RangeQuery. This implementation is generally preferable because it 
		/// a) Runs faster b) Does not have the scarcity of terms unduly influence score 
		/// c) avoids any "TooManyBooleanClauses" exception.
		/// However, if your application really needs to use the
		/// old-fashioned BooleanQuery expansion rewriting and the above
		/// points are not relevant then use this to change
		/// the rewrite method.
		/// </summary>
		public virtual void  SetMultiTermRewriteMethod(MultiTermQuery.RewriteMethod method)
		{
			multiTermRewriteMethod = method;
		}
		
		
		/// <seealso cref="setMultiTermRewriteMethod">
		/// </seealso>
		public virtual MultiTermQuery.RewriteMethod GetMultiTermRewriteMethod()
		{
			return multiTermRewriteMethod;
		}
		
		/// <summary> Set locale used by date range parsing.</summary>
		public virtual void  SetLocale(System.Globalization.CultureInfo locale)
		{
			this.locale = locale;
		}
		
		/// <summary> Returns current locale, allowing access by subclasses.</summary>
		public virtual System.Globalization.CultureInfo GetLocale()
		{
			return locale;
		}
		
		/// <summary> Sets the default date resolution used by RangeQueries for fields for which no
		/// specific date resolutions has been set. Field specific resolutions can be set
		/// with {@link #SetDateResolution(String, DateTools.Resolution)}.
		/// 
		/// </summary>
		/// <param name="dateResolution">the default date resolution to set
		/// </param>
		public virtual void  SetDateResolution(DateTools.Resolution dateResolution)
		{
			this.dateResolution = dateResolution;
		}
		
		/// <summary> Sets the date resolution used by RangeQueries for a specific field.
		/// 
		/// </summary>
		/// <param name="fieldName">field for which the date resolution is to be set 
		/// </param>
		/// <param name="dateResolution">date resolution to set
		/// </param>
		public virtual void  SetDateResolution(System.String fieldName, DateTools.Resolution dateResolution)
		{
			if (fieldName == null)
			{
				throw new System.ArgumentException("Field cannot be null.");
			}
			
			if (fieldToDateResolution == null)
			{
				// lazily initialize HashMap
				fieldToDateResolution = new System.Collections.Hashtable();
			}
			
			fieldToDateResolution[fieldName] = dateResolution;
		}
		
		/// <summary> Returns the date resolution that is used by RangeQueries for the given field. 
		/// Returns null, if no default or field specific date resolution has been set
		/// for the given field.
		/// 
		/// </summary>
		public virtual DateTools.Resolution GetDateResolution(System.String fieldName)
		{
			if (fieldName == null)
			{
				throw new System.ArgumentException("Field cannot be null.");
			}
			
			if (fieldToDateResolution == null)
			{
				// no field specific date resolutions set; return default date resolution instead
				return this.dateResolution;
			}
			
			DateTools.Resolution resolution = (DateTools.Resolution) fieldToDateResolution[fieldName];
			if (resolution == null)
			{
				// no date resolutions set for the given field; return default date resolution instead
				resolution = this.dateResolution;
			}
			
			return resolution;
		}
		
		/// <summary> Sets the collator used to determine index term inclusion in ranges
		/// for RangeQuerys.
		/// <p/>
		/// <strong>WARNING:</strong> Setting the rangeCollator to a non-null
		/// collator using this method will cause every single index Term in the
		/// Field referenced by lowerTerm and/or upperTerm to be examined.
		/// Depending on the number of index Terms in this Field, the operation could
		/// be very slow.
		/// 
		/// </summary>
		/// <param name="rc"> the collator to use when constructing RangeQuerys
		/// </param>
		public virtual void  SetRangeCollator(System.Globalization.CompareInfo rc)
		{
			rangeCollator = rc;
		}
		
		/// <returns> the collator used to determine index term inclusion in ranges
		/// for RangeQuerys.
		/// </returns>
		public virtual System.Globalization.CompareInfo GetRangeCollator()
		{
			return rangeCollator;
		}
		
		/// <deprecated> use {@link #AddClause(List, int, int, Query)} instead.
		/// </deprecated>
        [Obsolete("use AddClause(List, int, int, Query) instead.")]
		protected internal virtual void  AddClause(System.Collections.ArrayList clauses, int conj, int mods, Query q)
		{
			AddClause((System.Collections.IList) clauses, conj, mods, q);
		}
		
		protected internal virtual void  AddClause(System.Collections.IList clauses, int conj, int mods, Query q)
		{
			bool required, prohibited;
			
			// If this term is introduced by AND, make the preceding term required,
			// unless it's already prohibited
			if (clauses.Count > 0 && conj == CONJ_AND)
			{
				BooleanClause c = (BooleanClause) clauses[clauses.Count - 1];
				if (!c.IsProhibited())
					c.SetOccur(BooleanClause.Occur.MUST);
			}
			
			if (clauses.Count > 0 && operator_Renamed == AND_OPERATOR && conj == CONJ_OR)
			{
				// If this term is introduced by OR, make the preceding term optional,
				// unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b)
				// notice if the input is a OR b, first term is parsed as required; without
				// this modification a OR b would parsed as +a OR b
				BooleanClause c = (BooleanClause) clauses[clauses.Count - 1];
				if (!c.IsProhibited())
					c.SetOccur(BooleanClause.Occur.SHOULD);
			}
			
			// We might have been passed a null query; the term might have been
			// filtered away by the analyzer.
			if (q == null)
				return ;
			
			if (operator_Renamed == OR_OPERATOR)
			{
				// We set REQUIRED if we're introduced by AND or +; PROHIBITED if
				// introduced by NOT or -; make sure not to set both.
				prohibited = (mods == MOD_NOT);
				required = (mods == MOD_REQ);
				if (conj == CONJ_AND && !prohibited)
				{
					required = true;
				}
			}
			else
			{
				// We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED
				// if not PROHIBITED and not introduced by OR
				prohibited = (mods == MOD_NOT);
				required = (!prohibited && conj != CONJ_OR);
			}
			if (required && !prohibited)
				clauses.Add(NewBooleanClause(q, BooleanClause.Occur.MUST));
			else if (!required && !prohibited)
				clauses.Add(NewBooleanClause(q, BooleanClause.Occur.SHOULD));
			else if (!required && prohibited)
				clauses.Add(NewBooleanClause(q, BooleanClause.Occur.MUST_NOT));
			else
				throw new System.SystemException("Clause cannot be both required and prohibited");
		}
		
		
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		public /*protected internal*/ virtual Query GetFieldQuery(System.String field, System.String queryText)
		{
			// Use the analyzer to get all the tokens, and then build a TermQuery,
			// PhraseQuery, or nothing based on the term count
			
			TokenStream source;
			try
			{
				source = analyzer.ReusableTokenStream(field, new System.IO.StringReader(queryText));
				source.Reset();
			}
			catch (System.IO.IOException e)
			{
				source = analyzer.TokenStream(field, new System.IO.StringReader(queryText));
			}
			CachingTokenFilter buffer = new CachingTokenFilter(source);
			TermAttribute termAtt = null;
			PositionIncrementAttribute posIncrAtt = null;
			int numTokens = 0;
			
			bool success = false;
			try
			{
				buffer.Reset();
				success = true;
			}
			catch (System.IO.IOException e)
			{
				// success==false if we hit an exception
			}
			if (success)
			{
				if (buffer.HasAttribute(typeof(TermAttribute)))
				{
					termAtt = (TermAttribute) buffer.GetAttribute(typeof(TermAttribute));
				}
				if (buffer.HasAttribute(typeof(PositionIncrementAttribute)))
				{
					posIncrAtt = (PositionIncrementAttribute) buffer.GetAttribute(typeof(PositionIncrementAttribute));
				}
			}
			
			int positionCount = 0;
			bool severalTokensAtSamePosition = false;
			
			bool hasMoreTokens = false;
			if (termAtt != null)
			{
				try
				{
					hasMoreTokens = buffer.IncrementToken();
					while (hasMoreTokens)
					{
						numTokens++;
						int positionIncrement = (posIncrAtt != null)?posIncrAtt.GetPositionIncrement():1;
						if (positionIncrement != 0)
						{
							positionCount += positionIncrement;
						}
						else
						{
							severalTokensAtSamePosition = true;
						}
						hasMoreTokens = buffer.IncrementToken();
					}
				}
				catch (System.IO.IOException e)
				{
					// ignore
				}
			}
			try
			{
				// rewind the buffer stream
				buffer.Reset();
				
				// close original stream - all tokens buffered
				source.Close();
			}
			catch (System.IO.IOException e)
			{
				// ignore
			}
			
			if (numTokens == 0)
				return null;
			else if (numTokens == 1)
			{
				System.String term = null;
				try
				{
					bool hasNext = buffer.IncrementToken();
					System.Diagnostics.Debug.Assert(hasNext == true);
					term = termAtt.Term();
				}
				catch (System.IO.IOException e)
				{
					// safe to ignore, because we know the number of tokens
				}
				return NewTermQuery(new Term(field, term));
			}
			else
			{
				if (severalTokensAtSamePosition)
				{
					if (positionCount == 1)
					{
						// no phrase query:
						BooleanQuery q = NewBooleanQuery(true);
						for (int i = 0; i < numTokens; i++)
						{
							System.String term = null;
							try
							{
								bool hasNext = buffer.IncrementToken();
								System.Diagnostics.Debug.Assert(hasNext == true);
								term = termAtt.Term();
							}
							catch (System.IO.IOException e)
							{
								// safe to ignore, because we know the number of tokens
							}
							
							Query currentQuery = NewTermQuery(new Term(field, term));
							q.Add(currentQuery, BooleanClause.Occur.SHOULD);
						}
						return q;
					}
					else
					{
						// phrase query:
						MultiPhraseQuery mpq = NewMultiPhraseQuery();
						mpq.SetSlop(phraseSlop);
						System.Collections.ArrayList multiTerms = new System.Collections.ArrayList();
						int position = - 1;
						for (int i = 0; i < numTokens; i++)
						{
							System.String term = null;
							int positionIncrement = 1;
							try
							{
								bool hasNext = buffer.IncrementToken();
								System.Diagnostics.Debug.Assert(hasNext == true);
								term = termAtt.Term();
								if (posIncrAtt != null)
								{
									positionIncrement = posIncrAtt.GetPositionIncrement();
								}
							}
							catch (System.IO.IOException e)
							{
								// safe to ignore, because we know the number of tokens
							}
							
							if (positionIncrement > 0 && multiTerms.Count > 0)
							{
								if (enablePositionIncrements)
								{
                                    mpq.Add((Term[]) multiTerms.ToArray(typeof(Term)), position);
								}
								else
								{
                                    mpq.Add((Term[]) multiTerms.ToArray(typeof(Term)));
								}
								multiTerms.Clear();
							}
							position += positionIncrement;
							multiTerms.Add(new Term(field, term));
						}
						if (enablePositionIncrements)
						{
                            mpq.Add((Term[]) multiTerms.ToArray(typeof(Term)), position);
						}
						else
						{
                            mpq.Add((Term[]) multiTerms.ToArray(typeof(Term)));
						}
						return mpq;
					}
				}
				else
				{
					PhraseQuery pq = NewPhraseQuery();
					pq.SetSlop(phraseSlop);
					int position = - 1;
					
					
					for (int i = 0; i < numTokens; i++)
					{
						System.String term = null;
						int positionIncrement = 1;
						
						try
						{
							bool hasNext = buffer.IncrementToken();
							System.Diagnostics.Debug.Assert(hasNext == true);
							term = termAtt.Term();
							if (posIncrAtt != null)
							{
								positionIncrement = posIncrAtt.GetPositionIncrement();
							}
						}
						catch (System.IO.IOException e)
						{
							// safe to ignore, because we know the number of tokens
						}
						
						if (enablePositionIncrements)
						{
							position += positionIncrement;
							pq.Add(new Term(field, term), position);
						}
						else
						{
							pq.Add(new Term(field, term));
						}
					}
					return pq;
				}
			}
		}
		
		
		
		/// <summary> Base implementation delegates to {@link #GetFieldQuery(String,String)}.
		/// This method may be overridden, for example, to return
		/// a SpanNearQuery instead of a PhraseQuery.
		/// 
		/// </summary>
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		protected internal virtual Query GetFieldQuery(System.String field, System.String queryText, int slop)
		{
			Query query = GetFieldQuery(field, queryText);
			
			if (query is PhraseQuery)
			{
				((PhraseQuery) query).SetSlop(slop);
			}
			if (query is MultiPhraseQuery)
			{
				((MultiPhraseQuery) query).SetSlop(slop);
			}
			
			return query;
		}
		
		
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		protected internal virtual Query GetRangeQuery(System.String field, System.String part1, System.String part2, bool inclusive)
		{
			if (lowercaseExpandedTerms)
			{
				part1 = part1.ToLower();
				part2 = part2.ToLower();
			}
            try
            {
                System.DateTime d1;
                System.DateTime d2;

                try
                {
                    d1 = System.DateTime.Parse(part1, locale);
                }
                catch (System.Exception)
                {
                    d1 = System.DateTime.Parse(part1);
                }
                try
                {
                    d2 = System.DateTime.Parse(part2, locale);
                }
                catch (System.Exception)
                {
                    d2 = System.DateTime.Parse(part2);
                }

                if (inclusive)
                {
                    // The user can only specify the date, not the time, so make sure
                    // the time is set to the latest possible time of that date to really
                    // include all documents:
                    System.Globalization.Calendar cal = new System.Globalization.GregorianCalendar();
                    System.DateTime tempDate = d2;
                    d2 = d2.AddHours(23 - tempDate.Hour);
                    d2 = d2.AddMinutes(59 - tempDate.Minute);
                    d2 = d2.AddSeconds(59 - tempDate.Second);
                    d2 = d2.AddMilliseconds(999 - tempDate.Millisecond);
                }
                DateTools.Resolution resolution = GetDateResolution(field);
                if (resolution == null)
                {
                    // no default or field specific date resolution has been set,
					// use deprecated DateField to maintain compatibility with
                    // pre-1.9 Lucene versions.
                    part1 = DateField.DateToString(d1);
                    part2 = DateField.DateToString(d2);
                }
                else
                {
                    part1 = DateTools.DateToString(d1, resolution);
                    part2 = DateTools.DateToString(d2, resolution);
                }
            }
            catch (System.Exception)
            {
            }

            return NewRangeQuery(field, part1, part2, inclusive);
        }
		
		/// <summary> Builds a new BooleanQuery instance</summary>
		/// <param name="disableCoord">disable coord
		/// </param>
		/// <returns> new BooleanQuery instance
		/// </returns>
		protected internal virtual BooleanQuery NewBooleanQuery(bool disableCoord)
		{
			return new BooleanQuery(disableCoord);
		}
		
		/// <summary> Builds a new BooleanClause instance</summary>
		/// <param name="q">sub query
		/// </param>
		/// <param name="occur">how this clause should occur when matching documents
		/// </param>
		/// <returns> new BooleanClause instance
		/// </returns>
		protected internal virtual BooleanClause NewBooleanClause(Query q, BooleanClause.Occur occur)
		{
			return new BooleanClause(q, occur);
		}
		
		/// <summary> Builds a new TermQuery instance</summary>
		/// <param name="term">term
		/// </param>
		/// <returns> new TermQuery instance
		/// </returns>
		protected internal virtual Query NewTermQuery(Term term)
		{
			return new TermQuery(term);
		}
		
		/// <summary> Builds a new PhraseQuery instance</summary>
		/// <returns> new PhraseQuery instance
		/// </returns>
		protected internal virtual PhraseQuery NewPhraseQuery()
		{
			return new PhraseQuery();
		}
		
		/// <summary> Builds a new MultiPhraseQuery instance</summary>
		/// <returns> new MultiPhraseQuery instance
		/// </returns>
		protected internal virtual MultiPhraseQuery NewMultiPhraseQuery()
		{
			return new MultiPhraseQuery();
		}
		
		/// <summary> Builds a new PrefixQuery instance</summary>
		/// <param name="prefix">Prefix term
		/// </param>
		/// <returns> new PrefixQuery instance
		/// </returns>
		protected internal virtual Query NewPrefixQuery(Term prefix)
		{
			PrefixQuery query = new PrefixQuery(prefix);
			query.SetRewriteMethod(multiTermRewriteMethod);
			return query;
		}
		
		/// <summary> Builds a new FuzzyQuery instance</summary>
		/// <param name="term">Term
		/// </param>
		/// <param name="minimumSimilarity">minimum similarity
		/// </param>
		/// <param name="prefixLength">prefix length
		/// </param>
		/// <returns> new FuzzyQuery Instance
		/// </returns>
		protected internal virtual Query NewFuzzyQuery(Term term, float minimumSimilarity, int prefixLength)
		{
			// FuzzyQuery doesn't yet allow constant score rewrite
			return new FuzzyQuery(term, minimumSimilarity, prefixLength);
		}
		
		/// <summary> Builds a new TermRangeQuery instance</summary>
		/// <param name="field">Field
		/// </param>
		/// <param name="part1">min
		/// </param>
		/// <param name="part2">max
		/// </param>
		/// <param name="inclusive">true if range is inclusive
		/// </param>
		/// <returns> new TermRangeQuery instance
		/// </returns>
		protected internal virtual Query NewRangeQuery(System.String field, System.String part1, System.String part2, bool inclusive)
		{
			TermRangeQuery query = new TermRangeQuery(field, part1, part2, inclusive, inclusive, rangeCollator);
			query.SetRewriteMethod(multiTermRewriteMethod);
			return query;
		}
		
		/// <summary> Builds a new MatchAllDocsQuery instance</summary>
		/// <returns> new MatchAllDocsQuery instance
		/// </returns>
		protected internal virtual Query NewMatchAllDocsQuery()
		{
			return new MatchAllDocsQuery();
		}
		
		/// <summary> Builds a new WildcardQuery instance</summary>
		/// <param name="t">wildcard term
		/// </param>
		/// <returns> new WildcardQuery instance
		/// </returns>
		protected internal virtual Query NewWildcardQuery(Term t)
		{
			WildcardQuery query = new WildcardQuery(t);
			query.SetRewriteMethod(multiTermRewriteMethod);
			return query;
		}
		
		/// <summary> Factory method for generating query, given a set of clauses.
		/// By default creates a boolean query composed of clauses passed in.
		/// 
		/// Can be overridden by extending classes, to modify query being
		/// returned.
		/// 
		/// </summary>
		/// <param name="clauses">List that contains {@link BooleanClause} instances
		/// to join.
		/// 
		/// </param>
		/// <returns> Resulting {@link Query} object.
		/// </returns>
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		/// <deprecated> use {@link #GetBooleanQuery(List)} instead
		/// </deprecated>
        [Obsolete("use GetBooleanQuery(List) instead")]
		protected internal virtual Query GetBooleanQuery(System.Collections.ArrayList clauses)
		{
			return GetBooleanQuery((System.Collections.IList) clauses, false);
		}
		
		/// <summary> Factory method for generating query, given a set of clauses.
		/// By default creates a boolean query composed of clauses passed in.
		/// 
		/// Can be overridden by extending classes, to modify query being
		/// returned.
		/// 
		/// </summary>
		/// <param name="clauses">List that contains {@link BooleanClause} instances
		/// to join.
		/// 
		/// </param>
		/// <returns> Resulting {@link Query} object.
		/// </returns>
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		protected internal virtual Query GetBooleanQuery(System.Collections.IList clauses)
		{
			return GetBooleanQuery(clauses, false);
		}
		
		/// <summary> Factory method for generating query, given a set of clauses.
		/// By default creates a boolean query composed of clauses passed in.
		/// 
		/// Can be overridden by extending classes, to modify query being
		/// returned.
		/// 
		/// </summary>
		/// <param name="clauses">List that contains {@link BooleanClause} instances
		/// to join.
		/// </param>
		/// <param name="disableCoord">true if coord scoring should be disabled.
		/// 
		/// </param>
		/// <returns> Resulting {@link Query} object.
		/// </returns>
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		/// <deprecated> use {@link #GetBooleanQuery(List, boolean)} instead
		/// </deprecated>
        [Obsolete("use GetBooleanQuery(List, bool) instead")]
		protected internal virtual Query GetBooleanQuery(System.Collections.ArrayList clauses, bool disableCoord)
		{
			return GetBooleanQuery((System.Collections.IList) clauses, disableCoord);
		}
		
		/// <summary> Factory method for generating query, given a set of clauses.
		/// By default creates a boolean query composed of clauses passed in.
		/// 
		/// Can be overridden by extending classes, to modify query being
		/// returned.
		/// 
		/// </summary>
		/// <param name="clauses">List that contains {@link BooleanClause} instances
		/// to join.
		/// </param>
		/// <param name="disableCoord">true if coord scoring should be disabled.
		/// 
		/// </param>
		/// <returns> Resulting {@link Query} object.
		/// </returns>
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		protected internal virtual Query GetBooleanQuery(System.Collections.IList clauses, bool disableCoord)
		{
			if (clauses.Count == 0)
			{
				return null; // all clause words were filtered away by the analyzer.
			}
			BooleanQuery query = NewBooleanQuery(disableCoord);
			for (int i = 0; i < clauses.Count; i++)
			{
				query.Add((BooleanClause) clauses[i]);
			}
			return query;
		}
		
		/// <summary> Factory method for generating a query. Called when parser
		/// parses an input term token that contains one or more wildcard
		/// characters (? and *), but is not a prefix term token (one
		/// that has just a single * character at the end)
		/// <p/>
		/// Depending on settings, prefix term may be lower-cased
		/// automatically. It will not go through the default Analyzer,
		/// however, since normal Analyzers are unlikely to work properly
		/// with wildcard templates.
		/// <p/>
		/// Can be overridden by extending classes, to provide custom handling for
		/// wildcard queries, which may be necessary due to missing analyzer calls.
		/// 
		/// </summary>
		/// <param name="field">Name of the field query will use.
		/// </param>
		/// <param name="termStr">Term token that contains one or more wild card
		/// characters (? or *), but is not simple prefix term
		/// 
		/// </param>
		/// <returns> Resulting {@link Query} built for the term
		/// </returns>
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		public /*protected internal*/ virtual Query GetWildcardQuery(System.String field, System.String termStr)
		{
			if ("*".Equals(field))
			{
				if ("*".Equals(termStr))
					return NewMatchAllDocsQuery();
			}
			if (!allowLeadingWildcard && (termStr.StartsWith("*") || termStr.StartsWith("?")))
				throw new ParseException("'*' or '?' not allowed as first character in WildcardQuery");
			if (lowercaseExpandedTerms)
			{
				termStr = termStr.ToLower();
			}
			Term t = new Term(field, termStr);
			return NewWildcardQuery(t);
		}
		
		/// <summary> Factory method for generating a query (similar to
		/// {@link #getWildcardQuery}). Called when parser parses an input term
		/// token that uses prefix notation; that is, contains a single '*' wildcard
		/// character as its last character. Since this is a special case
		/// of generic wildcard term, and such a query can be optimized easily,
		/// this usually results in a different query object.
		/// <p/>
		/// Depending on settings, a prefix term may be lower-cased
		/// automatically. It will not go through the default Analyzer,
		/// however, since normal Analyzers are unlikely to work properly
		/// with wildcard templates.
		/// <p/>
		/// Can be overridden by extending classes, to provide custom handling for
		/// wild card queries, which may be necessary due to missing analyzer calls.
		/// 
		/// </summary>
		/// <param name="field">Name of the field query will use.
		/// </param>
		/// <param name="termStr">Term token to use for building term for the query
		/// (<b>without</b> trailing '*' character!)
		/// 
		/// </param>
		/// <returns> Resulting {@link Query} built for the term
		/// </returns>
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		public /*protected internal*/ virtual Query GetPrefixQuery(System.String field, System.String termStr)
		{
			if (!allowLeadingWildcard && termStr.StartsWith("*"))
				throw new ParseException("'*' not allowed as first character in PrefixQuery");
			if (lowercaseExpandedTerms)
			{
				termStr = termStr.ToLower();
			}
			Term t = new Term(field, termStr);
			return NewPrefixQuery(t);
		}
		
		/// <summary> Factory method for generating a query (similar to
		/// {@link #getWildcardQuery}). Called when parser parses
		/// an input term token that has the fuzzy suffix (~) appended.
		/// 
		/// </summary>
		/// <param name="field">Name of the field query will use.
		/// </param>
		/// <param name="termStr">Term token to use for building term for the query
		/// 
		/// </param>
		/// <returns> Resulting {@link Query} built for the term
		/// </returns>
		/// <exception cref="ParseException">throw in overridden method to disallow
		/// </exception>
		public /*protected internal*/ virtual Query GetFuzzyQuery(System.String field, System.String termStr, float minSimilarity)
		{
			if (lowercaseExpandedTerms)
			{
				termStr = termStr.ToLower();
			}
			Term t = new Term(field, termStr);
			return NewFuzzyQuery(t, minSimilarity, fuzzyPrefixLength);
		}
		
		/// <summary> Returns a String where the escape char has been
		/// removed, or kept only once if there was a double escape.
		/// 
		/// Supports escaped unicode characters, e. g. translates
		/// <code>\\u0041</code> to <code>A</code>.
		/// 
		/// </summary>
		private System.String DiscardEscapeChar(System.String input)
		{
			// Create char array to hold unescaped char sequence
			char[] output = new char[input.Length];
			
			// The length of the output can be less than the input
			// due to discarded escape chars. This variable holds
			// the actual length of the output
			int length = 0;
			
			// We remember whether the last processed character was 
			// an escape character
			bool lastCharWasEscapeChar = false;
			
			// The multiplier the current unicode digit must be multiplied with.
			// E. g. the first digit must be multiplied with 16^3, the second with 16^2...
			int codePointMultiplier = 0;
			
			// Used to calculate the codepoint of the escaped unicode character
			int codePoint = 0;
			
			for (int i = 0; i < input.Length; i++)
			{
				char curChar = input[i];
				if (codePointMultiplier > 0)
				{
					codePoint += HexToInt(curChar) * codePointMultiplier;
					codePointMultiplier = SupportClass.Number.URShift(codePointMultiplier, 4);
					if (codePointMultiplier == 0)
					{
						output[length++] = (char) codePoint;
						codePoint = 0;
					}
				}
				else if (lastCharWasEscapeChar)
				{
					if (curChar == 'u')
					{
						// found an escaped unicode character
						codePointMultiplier = 16 * 16 * 16;
					}
					else
					{
						// this character was escaped
						output[length] = curChar;
						length++;
					}
					lastCharWasEscapeChar = false;
				}
				else
				{
					if (curChar == '\\')
					{
						lastCharWasEscapeChar = true;
					}
					else
					{
						output[length] = curChar;
						length++;
					}
				}
			}
			
			if (codePointMultiplier > 0)
			{
				throw new ParseException("Truncated unicode escape sequence.");
			}
			
			if (lastCharWasEscapeChar)
			{
				throw new ParseException("Term can not end with escape character.");
			}
			
			return new System.String(output, 0, length);
		}
		
		/// <summary>Returns the numeric value of the hexadecimal character </summary>
		private static int HexToInt(char c)
		{
			if ('0' <= c && c <= '9')
			{
				return c - '0';
			}
			else if ('a' <= c && c <= 'f')
			{
				return c - 'a' + 10;
			}
			else if ('A' <= c && c <= 'F')
			{
				return c - 'A' + 10;
			}
			else
			{
				throw new ParseException("None-hex character in unicode escape sequence: " + c);
			}
		}
		
		/// <summary> Returns a String where those characters that QueryParser
		/// expects to be escaped are escaped by a preceding <code>\</code>.
		/// </summary>
		public static System.String Escape(System.String s)
		{
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			for (int i = 0; i < s.Length; i++)
			{
				char c = s[i];
				// These characters are part of the query syntax and must be escaped
				if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':' || c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~' || c == '*' || c == '?' || c == '|' || c == '&')
				{
					sb.Append('\\');
				}
				sb.Append(c);
			}
			return sb.ToString();
		}
		
		/// <summary> Command line tool to test QueryParser, using {@link Lucene.Net.Analysis.SimpleAnalyzer}.
		/// Usage:<br/>
		/// <code>java Lucene.Net.QueryParsers.QueryParser &lt;input&gt;</code>
		/// </summary>
		[STAThread]
		public static void  Main(System.String[] args)
		{
			if (args.Length == 0)
			{
				System.Console.Out.WriteLine("Usage: java Lucene.Net.QueryParsers.QueryParser <input>");
				System.Environment.Exit(0);
			}
			QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new Lucene.Net.Analysis.SimpleAnalyzer());
			Query q = qp.Parse(args[0]);
			System.Console.Out.WriteLine(q.ToString("field"));
		}
		
		// *   Query  ::= ( Clause )*
		// *   Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")" )
		public int Conjunction()
		{
			int ret = CONJ_NONE;
			switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
			{
				
				case Lucene.Net.QueryParsers.QueryParserConstants.AND: 
				case Lucene.Net.QueryParsers.QueryParserConstants.OR: 
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.AND: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.AND);
							ret = CONJ_AND;
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.OR: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.OR);
							ret = CONJ_OR;
							break;
						
						default: 
							jj_la1[0] = jj_gen;
							Jj_consume_token(- 1);
							throw new ParseException();
						
					}
					break;
				
				default: 
					jj_la1[1] = jj_gen;
					;
					break;
				
			}
			{
				if (true)
					return ret;
			}
			throw new System.ApplicationException("Missing return statement in function");
		}
		
		public int Modifiers()
		{
			int ret = MOD_NONE;
			switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
			{
				
				case Lucene.Net.QueryParsers.QueryParserConstants.NOT: 
				case Lucene.Net.QueryParsers.QueryParserConstants.PLUS: 
				case Lucene.Net.QueryParsers.QueryParserConstants.MINUS: 
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.PLUS: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.PLUS);
							ret = MOD_REQ;
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.MINUS: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.MINUS);
							ret = MOD_NOT;
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.NOT: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NOT);
							ret = MOD_NOT;
							break;
						
						default: 
							jj_la1[2] = jj_gen;
							Jj_consume_token(- 1);
							throw new ParseException();
						
					}
					break;
				
				default: 
					jj_la1[3] = jj_gen;
					;
					break;
				
			}
			{
				if (true)
					return ret;
			}
			throw new System.ApplicationException("Missing return statement in function");
		}
		
		// This makes sure that there is no garbage after the query string
		public Query TopLevelQuery(System.String field)
		{
			Query q;
			q = Query(field);
			Jj_consume_token(0);
			{
				if (true)
					return q;
			}
			throw new System.ApplicationException("Missing return statement in function");
		}
		
		public Query Query(System.String field)
		{
			System.Collections.IList clauses = new System.Collections.ArrayList();
			Query q, firstQuery = null;
			int conj, mods;
			mods = Modifiers();
			q = Clause(field);
			AddClause(clauses, CONJ_NONE, mods, q);
			if (mods == MOD_NONE)
				firstQuery = q;
			while (true)
			{
				switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
				{
					
					case Lucene.Net.QueryParsers.QueryParserConstants.AND: 
					case Lucene.Net.QueryParsers.QueryParserConstants.OR: 
					case Lucene.Net.QueryParsers.QueryParserConstants.NOT: 
					case Lucene.Net.QueryParsers.QueryParserConstants.PLUS: 
					case Lucene.Net.QueryParsers.QueryParserConstants.MINUS: 
					case Lucene.Net.QueryParsers.QueryParserConstants.LPAREN: 
					case Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
					case Lucene.Net.QueryParsers.QueryParserConstants.QUOTED: 
					case Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
					case Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: 
					case Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: 
					case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START: 
					case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START: 
					case Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: 
						;
						break;
					
					default: 
						jj_la1[4] = jj_gen;
						goto label_1_brk;   // {{Aroush-2.9}} this goto maybe misplaced
					
				}
				conj = Conjunction();
				mods = Modifiers();
				q = Clause(field);
				AddClause(clauses, conj, mods, q);
			}

label_1_brk: ;  // {{Aroush-2.9}} this lable maybe misplaced
			
			if (clauses.Count == 1 && firstQuery != null)
			{
				if (true)
					return firstQuery;
			}
			else
			{
				{
					if (true)
						return GetBooleanQuery(clauses);
				}
			}
			throw new System.ApplicationException("Missing return statement in function");
		}
		
		public Query Clause(System.String field)
		{
			Query q;
			Token fieldToken = null, boost = null;
			if (Jj_2_1(2))
			{
				switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
				{
					
					case Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
						fieldToken = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.TERM);
						Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.COLON);
						field = DiscardEscapeChar(fieldToken.image);
						break;
					
					case Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
						Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.STAR);
						Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.COLON);
						field = "*";
						break;
					
					default: 
						jj_la1[5] = jj_gen;
						Jj_consume_token(- 1);
						throw new ParseException();
					
				}
			}
			else
			{
				;
			}
			switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
			{
				
				case Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
				case Lucene.Net.QueryParsers.QueryParserConstants.QUOTED: 
				case Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
				case Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: 
				case Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: 
				case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START: 
				case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START: 
				case Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: 
					q = Term(field);
					break;
				
				case Lucene.Net.QueryParsers.QueryParserConstants.LPAREN: 
					Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.LPAREN);
					q = Query(field);
					Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RPAREN);
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
							boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
							break;
						
						default: 
							jj_la1[6] = jj_gen;
							;
							break;
						
					}
					break;
				
				default: 
					jj_la1[7] = jj_gen;
					Jj_consume_token(- 1);
					throw new ParseException();
				
			}
			if (boost != null)
			{
				float f = (float) 1.0;
				try
				{
					f = (float) SupportClass.Single.Parse(boost.image);
					q.SetBoost(f);
				}
				catch (System.Exception ignored)
				{
				}
			}
			{
				if (true)
					return q;
			}
			throw new System.ApplicationException("Missing return statement in function");
		}
		
		public Query Term(System.String field)
		{
			Token term, boost = null, fuzzySlop = null, goop1, goop2;
			bool prefix = false;
			bool wildcard = false;
			bool fuzzy = false;
			Query q;
			switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
			{
				
				case Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
				case Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
				case Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: 
				case Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: 
				case Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: 
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
							term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.TERM);
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
							term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.STAR);
							wildcard = true;
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: 
							term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM);
							prefix = true;
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: 
							term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM);
							wildcard = true;
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: 
							term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
							break;
						
						default: 
							jj_la1[8] = jj_gen;
							Jj_consume_token(- 1);
							throw new ParseException();
						
					}
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP: 
							fuzzySlop = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP);
							fuzzy = true;
							break;
						
						default: 
							jj_la1[9] = jj_gen;
							;
							break;
						
					}
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
							boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
							switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
							{
								
								case Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP: 
									fuzzySlop = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP);
									fuzzy = true;
									break;
								
								default: 
									jj_la1[10] = jj_gen;
									;
									break;
								
							}
							break;
						
						default: 
							jj_la1[11] = jj_gen;
							;
							break;
						
					}
					System.String termImage = DiscardEscapeChar(term.image);
					if (wildcard)
					{
						q = GetWildcardQuery(field, termImage);
					}
					else if (prefix)
					{
						q = GetPrefixQuery(field, DiscardEscapeChar(term.image.Substring(0, (term.image.Length - 1) - (0))));
					}
					else if (fuzzy)
					{
						float fms = fuzzyMinSim;
						try
						{
							fms = (float) SupportClass.Single.Parse(fuzzySlop.image.Substring(1));
						}
						catch (System.Exception ignored)
						{
						}
						if (fms < 0.0f || fms > 1.0f)
						{
							{
								if (true)
									throw new ParseException("Minimum similarity for a FuzzyQuery has to be between 0.0f and 1.0f !");
							}
						}
						q = GetFuzzyQuery(field, termImage, fms);
					}
					else
					{
						q = GetFieldQuery(field, termImage);
					}
					break;
				
				case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START: 
					Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START);
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP: 
							goop1 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP);
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED: 
							goop1 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED);
							break;
						
						default: 
							jj_la1[12] = jj_gen;
							Jj_consume_token(- 1);
							throw new ParseException();
						
					}
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_TO: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_TO);
							break;
						
						default: 
							jj_la1[13] = jj_gen;
							;
							break;
						
					}
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP: 
							goop2 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP);
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED: 
							goop2 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED);
							break;
						
						default: 
							jj_la1[14] = jj_gen;
							Jj_consume_token(- 1);
							throw new ParseException();
						
					}
					Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_END);
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
							boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
							break;
						
						default: 
							jj_la1[15] = jj_gen;
							;
							break;
						
					}
					if (goop1.kind == Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED)
					{
						goop1.image = goop1.image.Substring(1, (goop1.image.Length - 1) - (1));
					}
					if (goop2.kind == Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED)
					{
						goop2.image = goop2.image.Substring(1, (goop2.image.Length - 1) - (1));
					}
					q = GetRangeQuery(field, DiscardEscapeChar(goop1.image), DiscardEscapeChar(goop2.image), true);
					break;
				
				case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START: 
					Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START);
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP: 
							goop1 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP);
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED: 
							goop1 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED);
							break;
						
						default: 
							jj_la1[16] = jj_gen;
							Jj_consume_token(- 1);
							throw new ParseException();
						
					}
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_TO: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_TO);
							break;
						
						default: 
							jj_la1[17] = jj_gen;
							;
							break;
						
					}
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP: 
							goop2 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP);
							break;
						
						case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED: 
							goop2 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED);
							break;
						
						default: 
							jj_la1[18] = jj_gen;
							Jj_consume_token(- 1);
							throw new ParseException();
						
					}
					Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_END);
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
							boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
							break;
						
						default: 
							jj_la1[19] = jj_gen;
							;
							break;
						
					}
					if (goop1.kind == Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED)
					{
						goop1.image = goop1.image.Substring(1, (goop1.image.Length - 1) - (1));
					}
					if (goop2.kind == Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED)
					{
						goop2.image = goop2.image.Substring(1, (goop2.image.Length - 1) - (1));
					}
					
					q = GetRangeQuery(field, DiscardEscapeChar(goop1.image), DiscardEscapeChar(goop2.image), false);
					break;
				
				case Lucene.Net.QueryParsers.QueryParserConstants.QUOTED: 
					term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.QUOTED);
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP: 
							fuzzySlop = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP);
							break;
						
						default: 
							jj_la1[20] = jj_gen;
							;
							break;
						
					}
					switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
					{
						
						case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
							Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
							boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
							break;
						
						default: 
							jj_la1[21] = jj_gen;
							;
							break;
						
					}
					int s = phraseSlop;
					
					if (fuzzySlop != null)
					{
						try
						{
							s = (int) SupportClass.Single.Parse(fuzzySlop.image.Substring(1));
						}
						catch (System.Exception ignored)
						{
						}
					}
					q = GetFieldQuery(field, DiscardEscapeChar(term.image.Substring(1, (term.image.Length - 1) - (1))), s);
					break;
				
				default: 
					jj_la1[22] = jj_gen;
					Jj_consume_token(- 1);
					throw new ParseException();
				
			}
			if (boost != null)
			{
				float f = (float) 1.0;
				try
				{
					f = (float) SupportClass.Single.Parse(boost.image);
				}
				catch (System.Exception ignored)
				{
					/* Should this be handled somehow? (defaults to "no boost", if
					* boost number is invalid)
					*/
				}
				
				// avoid boosting null queries, such as those caused by stop words
				if (q != null)
				{
					q.SetBoost(f);
				}
			}
			{
				if (true)
					return q;
			}
			throw new System.ApplicationException("Missing return statement in function");
		}
		
		private bool Jj_2_1(int xla)
		{
			jj_la = xla; jj_lastpos = jj_scanpos = token;
			try
			{
				return !Jj_3_1();
			}
			catch (LookaheadSuccess ls)
			{
				return true;
			}
			finally
			{
				Jj_save(0, xla);
			}
		}
		
		private bool Jj_3R_2()
		{
			if (Jj_scan_token(Lucene.Net.QueryParsers.QueryParserConstants.TERM))
				return true;
			if (Jj_scan_token(Lucene.Net.QueryParsers.QueryParserConstants.COLON))
				return true;
			return false;
		}
		
		private bool Jj_3_1()
		{
			Token xsp;
			xsp = jj_scanpos;
			if (Jj_3R_2())
			{
				jj_scanpos = xsp;
				if (Jj_3R_3())
					return true;
			}
			return false;
		}
		
		private bool Jj_3R_3()
		{
			if (Jj_scan_token(Lucene.Net.QueryParsers.QueryParserConstants.STAR))
				return true;
			if (Jj_scan_token(Lucene.Net.QueryParsers.QueryParserConstants.COLON))
				return true;
			return false;
		}
		
		/// <summary>Generated Token Manager. </summary>
		public QueryParserTokenManager token_source;
		/// <summary>Current token. </summary>
		public Token token;
		/// <summary>Next token. </summary>
		public Token jj_nt;
		private int jj_ntk;
		private Token jj_scanpos, jj_lastpos;
		private int jj_la;
		private int jj_gen;
		private int[] jj_la1 = new int[23];
		private static int[] jj_la1_0;
		private static int[] jj_la1_1;
		private static void  Jj_la1_init_0()
		{
			jj_la1_0 = new int[]{0x300, 0x300, 0x1c00, 0x1c00, 0x3ed3f00, 0x90000, 0x20000, 0x3ed2000, 0x2690000, 0x100000, 0x100000, 0x20000, 0x30000000, 0x4000000, 0x30000000, 0x20000, 0x0, 0x40000000, 0x0, 0x20000, 0x100000, 0x20000, 0x3ed0000};
		}
		private static void  Jj_la1_init_1()
		{
			jj_la1_1 = new int[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0};
		}
		private JJCalls[] jj_2_rtns;
		private bool jj_rescan = false;
		private int jj_gc = 0;
		
		/// <summary>Constructor with user supplied CharStream. </summary>
		protected internal QueryParser(CharStream stream)
		{
			InitBlock();
			token_source = new QueryParserTokenManager(stream);
			token = new Token();
			jj_ntk = - 1;
			jj_gen = 0;
			for (int i = 0; i < 23; i++)
				jj_la1[i] = - 1;
			for (int i = 0; i < jj_2_rtns.Length; i++)
				jj_2_rtns[i] = new JJCalls();
		}
		
		/// <summary>Reinitialise. </summary>
		public virtual void  ReInit(CharStream stream)
		{
			token_source.ReInit(stream);
			token = new Token();
			jj_ntk = - 1;
			jj_gen = 0;
			for (int i = 0; i < 23; i++)
				jj_la1[i] = - 1;
			for (int i = 0; i < jj_2_rtns.Length; i++)
				jj_2_rtns[i] = new JJCalls();
		}
		
		/// <summary>Constructor with generated Token Manager. </summary>
		protected internal QueryParser(QueryParserTokenManager tm)
		{
			InitBlock();
			token_source = tm;
			token = new Token();
			jj_ntk = - 1;
			jj_gen = 0;
			for (int i = 0; i < 23; i++)
				jj_la1[i] = - 1;
			for (int i = 0; i < jj_2_rtns.Length; i++)
				jj_2_rtns[i] = new JJCalls();
		}
		
		/// <summary>Reinitialise. </summary>
		public virtual void  ReInit(QueryParserTokenManager tm)
		{
			token_source = tm;
			token = new Token();
			jj_ntk = - 1;
			jj_gen = 0;
			for (int i = 0; i < 23; i++)
				jj_la1[i] = - 1;
			for (int i = 0; i < jj_2_rtns.Length; i++)
				jj_2_rtns[i] = new JJCalls();
		}
		
		private Token Jj_consume_token(int kind)
		{
			Token oldToken;
			if ((oldToken = token).next != null)
				token = token.next;
			else
				token = token.next = token_source.GetNextToken();
			jj_ntk = - 1;
			if (token.kind == kind)
			{
				jj_gen++;
				if (++jj_gc > 100)
				{
					jj_gc = 0;
					for (int i = 0; i < jj_2_rtns.Length; i++)
					{
						JJCalls c = jj_2_rtns[i];
						while (c != null)
						{
							if (c.gen < jj_gen)
								c.first = null;
							c = c.next;
						}
					}
				}
				return token;
			}
			token = oldToken;
			jj_kind = kind;
			throw GenerateParseException();
		}
		
		[Serializable]
		private sealed class LookaheadSuccess:System.ApplicationException
		{
		}
		private LookaheadSuccess jj_ls;
		private bool Jj_scan_token(int kind)
		{
			if (jj_scanpos == jj_lastpos)
			{
				jj_la--;
				if (jj_scanpos.next == null)
				{
					jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.GetNextToken();
				}
				else
				{
					jj_lastpos = jj_scanpos = jj_scanpos.next;
				}
			}
			else
			{
				jj_scanpos = jj_scanpos.next;
			}
			if (jj_rescan)
			{
				int i = 0; Token tok = token;
				while (tok != null && tok != jj_scanpos)
				{
					i++; tok = tok.next;
				}
				if (tok != null)
					Jj_add_error_token(kind, i);
			}
			if (jj_scanpos.kind != kind)
				return true;
			if (jj_la == 0 && jj_scanpos == jj_lastpos)
				throw jj_ls;
			return false;
		}
		
		
		/// <summary>Get the next Token. </summary>
		public Token GetNextToken()
		{
			if (token.next != null)
				token = token.next;
			else
				token = token.next = token_source.GetNextToken();
			jj_ntk = - 1;
			jj_gen++;
			return token;
		}
		
		/// <summary>Get the specific Token. </summary>
		public Token GetToken(int index)
		{
			Token t = token;
			for (int i = 0; i < index; i++)
			{
				if (t.next != null)
					t = t.next;
				else
					t = t.next = token_source.GetNextToken();
			}
			return t;
		}
		
		private int Jj_ntk()
		{
			if ((jj_nt = token.next) == null)
				return (jj_ntk = (token.next = token_source.GetNextToken()).kind);
			else
				return (jj_ntk = jj_nt.kind);
		}
		
		private System.Collections.IList jj_expentries = new System.Collections.ArrayList();
		private int[] jj_expentry;
		private int jj_kind = - 1;
		private int[] jj_lasttokens = new int[100];
		private int jj_endpos;
		
		private void  Jj_add_error_token(int kind, int pos)
		{
			if (pos >= 100)
				return ;
			if (pos == jj_endpos + 1)
			{
				jj_lasttokens[jj_endpos++] = kind;
			}
			else if (jj_endpos != 0)
			{
				jj_expentry = new int[jj_endpos];
				for (int i = 0; i < jj_endpos; i++)
				{
					jj_expentry[i] = jj_lasttokens[i];
				}
				if (pos != 0)
					jj_lasttokens[(jj_endpos = pos) - 1] = kind;
			}
		}
		
		/// <summary>Generate ParseException. </summary>
		public virtual ParseException GenerateParseException()
		{
			jj_expentries.Clear();
			bool[] la1tokens = new bool[34];
			if (jj_kind >= 0)
			{
				la1tokens[jj_kind] = true;
				jj_kind = - 1;
			}
			for (int i = 0; i < 23; i++)
			{
				if (jj_la1[i] == jj_gen)
				{
					for (int j = 0; j < 32; j++)
					{
						if ((jj_la1_0[i] & (1 << j)) != 0)
						{
							la1tokens[j] = true;
						}
						if ((jj_la1_1[i] & (1 << j)) != 0)
						{
							la1tokens[32 + j] = true;
						}
					}
				}
			}
			for (int i = 0; i < 34; i++)
			{
				if (la1tokens[i])
				{
					jj_expentry = new int[1];
					jj_expentry[0] = i;
					jj_expentries.Add(jj_expentry);
				}
			}
			jj_endpos = 0;
			Jj_rescan_token();
			Jj_add_error_token(0, 0);
			int[][] exptokseq = new int[jj_expentries.Count][];
			for (int i = 0; i < jj_expentries.Count; i++)
			{
				exptokseq[i] = (int[]) jj_expentries[i];
			}
			return new ParseException(token, exptokseq, Lucene.Net.QueryParsers.QueryParserConstants.tokenImage);
		}
		
		/// <summary>Enable tracing. </summary>
		public void  Enable_tracing()
		{
		}
		
		/// <summary>Disable tracing. </summary>
		public void  Disable_tracing()
		{
		}
		
		private void  Jj_rescan_token()
		{
			jj_rescan = true;
			for (int i = 0; i < 1; i++)
			{
				try
				{
					JJCalls p = jj_2_rtns[i];
					do 
					{
						if (p.gen > jj_gen)
						{
							jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
							switch (i)
							{
								
								case 0:  Jj_3_1(); break;
								}
						}
						p = p.next;
					}
					while (p != null);
				}
				catch (LookaheadSuccess ls)
				{
				}
			}
			jj_rescan = false;
		}
		
		private void  Jj_save(int index, int xla)
		{
			JJCalls p = jj_2_rtns[index];
			while (p.gen > jj_gen)
			{
				if (p.next == null)
				{
					p = p.next = new JJCalls(); break;
				}
				p = p.next;
			}
			p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
		}
		
		internal sealed class JJCalls
		{
			internal int gen;
			internal Token first;
			internal int arg;
			internal JJCalls next;
		}
		static QueryParser()
		{
			{
				Jj_la1_init_0();
				Jj_la1_init_1();
			}
		}
	}
}